<!--
Copyright 2013 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Steph McArthur
-->

<!DOCTYPE html>
<div id="anim"></div>

<script src="../bootstrap.js" nochecks></script>
<script>
var animation = new Animation(document.getElementById("anim"), {left: "100px"});
var dt = document.timeline;

// Test Player.timeline.
var player1 = dt.play(animation);
test(function() {assert_equals(player1.timeline,  document.timeline)},
     "Player.timeline incorrect");

// Test that TimedItem.player and Player.source are consistent.
test(function() {assert_not_equals(player1,  null)},
     "Player should not be null");
test(function() {assert_equals(player1.source,  animation)},
     "Player.source incorrect");
test(function() {assert_equals(animation.player,  player1)},
     "TimedItem.player incorrect");

// Test that play() always returns a new Player.
var player2 = dt.play(animation);
test(function() {assert_not_equals(player2,  player1)},
     "Repeated calls to play() should create a new Player");
test(function() {assert_equals(animation.player,  player2)},
     "Repeated play(): TimedItem.player incorrect");
test(function() {assert_equals(player2.source,  animation)},
     "Repeated play(): Player.source incorrect");
test(function() {assert_equals(player2.startTime,  player1.startTime)},
     "Repeated play(): players should have same start time");

// Test explicit setting of Player.source.
player1.source = animation;
test(function() {assert_equals(player2.source,  null)},
     "Set Player.source: Old Player.source incorrect");
test(function() {assert_equals(player1.source,  animation)},
     "Set Player.source: New Player.source incorrect");
test(function() {assert_equals(animation.player,  player1)},
     "Set Player.source: TimedItem.player incorrect");

// Test that TimedItem.player gives null on a detached tree.
var animation2 =
    new Animation(document.getElementById("anim"), {left: "100px"});
var parGroup = new ParGroup([animation2]);
test(function() {assert_equals(parGroup.player,  null)},
     "TimedItem.player should be null for root");
test(function() {assert_equals(animation2.player,  null)},
     "TimedItem.player should be null for leaf");

// Test that TimedItem.player remotes to the root of the tree.
var player3 = dt.play(parGroup);
test(function() {assert_equals(animation2.player,  player3)},
     "TimedItem.player should remote");

// Test that calling play() on a TimedItem with a parent results in
// reparenting.
var player4 = dt.play(animation2);
test(function() {assert_equals(animation2.parent,  null)},
     "Animation should be reparented");
test(function() {assert_equals(parGroup.children.length, 0)},
     "Animation parent should be updated, leaving parGroup.children.length = 0");
test(function() {assert_equals(player4.source,  animation2)},
     "Player should use reparented animation");

// Test that setting a parent on a TimedItem with a Player causes the player to
// be disconnected.
parGroup.append(animation2);
test(function() {assert_equals(parGroup.player,  player3)},
     "TimedItem.player should be updated for root");
test(function() {assert_equals(animation2.player,  player3)},
     "TimedItem.player should be updated for leaf");
test(function() {assert_equals(player4.source,  null)},
     "Player.source should be updated");
test(function() {assert_equals(animation2.parent,  parGroup)},
     "Animation.parent should be updated");
test(function() {assert_equals(parGroup.children.length,  1)},
      "Animation parent should be updated, leaving parGroup.children.length = 1");
test(function() {assert_equals(parGroup.children[0],  animation2)},
     "Animation parent should be updated");

// Test that currentTime is zero before timeline starts.
test(function() {assert_equals(document.timeline.play(animation).currentTime,  0)},
     "currentTime should be zero before Timeline starts");

// Test that startTime is zero before timeline starts.
test(function() {assert_equals(document.timeline.play(animation).startTime,  0)},
     "startTime should be zero before Timeline starts");

// Test that setting currentTime has no effect until the timeline starts.
var player5 = dt.play(animation);
player5.currentTime = 42;
test(function() {assert_equals(player5.currentTime,  0)},
     "player5's currentTime should always be zero before Timeline starts");
timing_test(function() {
    at(0.1, function() {assert_true(player5.currentTime > 42)});
  }, "player5's updates to currentTime should take effect after Timeline starts");

// Test that setting startTime has no effect until the timeline starts.
var player6 = dt.play(animation);
player6.startTime = 42;
test(function() {assert_equals(player6.currentTime,  0)},
     "player6's currentTime should always be zero before Timeline starts");
timing_test(function() {
    at(0.1, function() {assert_true(player6.currentTime < -41)});
  }, "player6's updates to startTime should take effect after Timeline starts");

// Test that a Player's TimedItem gets a null inherited time until the
// timeline starts.
var animation1 = new Animation(document.getElementById("anim"), {left: "100px"});
dt.play(animation1);
test(function() {assert_equals(animation1.localTime, null)},
     "TimedItem's inherited time, and thus " +
     "localTime should be null before Timeline starts");
timing_test(function() {
    at(0.0, function() {assert_not_equals(animation1.localTime, null)});
  }, "TimedItem's inherited time " +
     "and thus localTime should not be null after Timeline starts");

// Test that TimedItem is updated immediately on calling Timeline.play() after
// the timeline starts.
var animation4 = new Animation(
   document.getElementById("anim"), {left: "100px"});
test(function() {assert_equals(animation4.localTime,  null)},
     "localTime should be null before playing");
timing_test(function() {
    at(0.0, function() {
      document.timeline.play(animation4);
      assert_equals(animation4.localTime,  0)
    });
  }, "localTime should be set by playing");

// Test that updates to currentTime take immediate effect.
timing_test(function() {
    at(0.0, function() {
      var animation5 = new Animation(
        document.getElementById("anim"), {left: "100px"});
      document.timeline.play(animation5).currentTime = 42;
      assert_equals(animation5.localTime,  42);
    });
  }, "Updates to Player.currentTime should take immediate effect");

// Test that updates to startTime take immediate effect.
timing_test(function() {
    at(0.0, function() {
      var animation6 = new Animation(
        document.getElementById("anim"), {left: "100px"});
      document.timeline.play(animation6).startTime = 42;
      assert_equals(animation6.localTime < -41,  true);
    });
  }, "Updates to Player.startTime should take immediate effect");

// Test that updates to source take immediate effect.
timing_test(function() {
    at(0.0, function() {
      var player = document.timeline.play(new Animation(
        document.getElementById("anim"), {left: "100px"}));
      var animation7 = new Animation(
        document.getElementById("anim"), {left: "100px"});
      player.source = animation7;
      assert_equals(animation7.localTime,  0);
    });
  }, "Updates to Player.source should take immediate effect");

</script>
